package edu.utn.tacs.gestion.domain.impl;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;

import edu.utn.tacs.gestion.domain.interfaces.IUsuario;
import edu.utn.tacs.gestion.exception.BusinessException;
import edu.utn.tacs.gestion.service.impl.GestionEventosService;

/**
 * Representacion de un usuario en el dominio de negocio<li>El usuario crea un evento como en una red social</li>
 * <li>Cuenta con una lista de sus eventos creados</li><li>Cuenta con una lista de los eventos a los cuales se registro</li>
 * <li>El usuario puede realizar comentarios acerca de los eventos a los que asistio</li>
 */
public class Usuario implements IUsuario {
		
	private Long nroDocumento;
	private String nombre;
	private String comentario = "";
	private Set<Evento> eventosCreados = new HashSet<Evento>();
	static Logger logger = Logger.getLogger(Usuario.class);
	
	public Usuario(){};
	
	public Usuario(Long nroDocumento, String nombre) {
		this.nroDocumento = nroDocumento;
		this.nombre = nombre;
	}
	
	public Long getNroDocumento() {
		return nroDocumento;
	}
	
	public void setNroDocumento(Long nroDocumento) {
		this.nroDocumento = nroDocumento;
	}
	
	public String getNombre() {
		return nombre;
	}
	
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	
	public String getComentario() {
		return comentario;
	}

	public void setComentario(String comentario) {
		this.comentario = comentario;
	}
	
	/**
	 * 
	 * @return eventosCreados: los eventos creados por el usuario
	 */
	public Set<Evento> getEventosCreados() {
		return eventosCreados;
	}
	
	public void setEventosCreados(Set<Evento> eventosCreados) {
		this.eventosCreados = eventosCreados;
	}
	
	/**
	 * Permite crear un evento<li>Se registra al usuario que crea el evento</li>
	 */
	public Evento crearEvento(String nombre, String descripcion, Date fecha, double duracion, String ubicacion) throws BusinessException {
		logger.debug("Metodo: crearEvento()");
		Evento evento = new Evento(this, nombre, fecha, duracion, descripcion);
		evento.setUbicacion(ubicacion);
		evento.getUsuariosRegistrados().add(this); 
		if (GestionEventosService.getInstance().existeEvento(evento)) {
			logger.error("BusinessException:  Ya existe el evento que se intenta crear");
			throw new BusinessException("Ya existe el evento que se intenta crear");
		}
		if (this.eventosCreados.contains(evento)) {
			logger.error("BusinessException:  Ya existe el evento que se intenta crear");
			throw new BusinessException("Ya existe el evento que se intenta crear");
		}
		this.eventosCreados.add(evento);
		logger.info("Evento creado por Usuario: " + this.nombre + " el " + new Date() + " ");
		logger.info("Evento: " + evento.getNombre() + " - el " + evento.getFecha() + " en " + evento.getUbicacion() );
		return evento;
	}
	
	
	/**
	 * Busca un evento en la lista de eventos creados por el usuario
	 * @param nombre
	 * @param fecha
	 * @return evento si es encontrado, null si no se encuentra
	 */
	public Evento findEvento(String nombre, Date fecha) {
		logger.debug("Metodo: findEvento()");
		for(Evento evento: this.eventosCreados) {
			if (evento.getNombre().equals(nombre) && (evento.getFecha().equals(fecha))) {
				logger.info("Evento: " + evento.getNombre() + " con fecha " + evento.getFecha());
				return evento;
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((nroDocumento == null) ? 0 : nroDocumento.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Usuario))
			return false;
		Usuario other = (Usuario) obj;
		if (nroDocumento == null) {
			if (other.nroDocumento != null)
				return false;
		} else if (!nroDocumento.equals(other.nroDocumento))
			return false;
		return true;
	}

	
}
